home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc™ Source Code / UI / WinStat.cpp < prev    next >
Encoding:
Text File  |  1996-08-28  |  65.0 KB  |  2,418 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        WinStat.cpp
  3.  
  4.     Contains:    Definition of ODWindowState class
  5.  
  6.     Owned by:    Chris Linn
  7.  
  8.     Copyright:    © 1994 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <4>     7/31/96    CSL        1373366: Problem with hidden floating
  13.                                     windows
  14.          <3>     6/21/96    CSL        1315410: Windows won't select properly.
  15.                                     1331320: New windows shown hilited when
  16.                                     opened with process in background.
  17.          <2>     1/15/96    TJ        Cleaned Up
  18.         <82>     11/2/95    RR        #1298525, 1298642 Internalize now uses a
  19.                                     SUView on the draftsProperties, and checks
  20.                                     for reference validity
  21.         <81>    10/26/95    eeh        1296308: deal with non-persistant frames in
  22.                                     Internalize
  23.         <80>    10/24/95    RR        #1295596 OpenWindows no longer calls
  24.                                     select() during normal document open.
  25.         <79>    10/18/95    RR        1289153: Recover from exceptions creating /
  26.                                                                         internalizing / registering
  27.                                     windows. Added TRY/CATCH in CATCH block of
  28.                                     ::INnternalize
  29.         <78>    10/17/95    jpa        1289153: Recover from exceptions creating /
  30.                                     internalizing / registering windows.
  31.         <77>    10/16/95    RR        #1293067 Pass shouldDispose to
  32.                                     RegisterWindow
  33.         <76>     10/8/95    TJ        Fixes Recomended by Refball
  34.         <75>     10/3/95    eeh        1287095: use ReleaseObject in
  35.                                     RegisterWindow
  36.         <74>     10/3/95    TJ        Changes done by RefBall Team
  37.         <73>     9/21/95    RR        # 1285189 AcquireFrontWindow calls
  38.                                     FrontWindow() rather than
  39.                                     GetFrontNonFloatingWindow
  40.         <72>     9/13/95    TÇ        1282067 FB3:  UI temp var before SOM_TRY
  41.         <71>     9/12/95    RR        #1274439 Don't activate/deactivate windows
  42.                                     when in background
  43.         <70>      9/6/95    RR        #(1236387) Deactivate before suspend.
  44.                                     Reactivate after Resume
  45.         <69>      9/1/95    RR        # 1279100/1280338 Added IsActive test to
  46.                                     SelectODWindow
  47.         <68>     8/26/95    TÇ        1274606 FB2: Patching Remarks
  48.         <67>     8/25/95    JBS        1263078 FB: fix part editor swapping
  49.         <66>     8/15/95    RR        # 1233767 Use window iterator in
  50.                                     SuspendResume
  51.         <65>     8/12/95    TÇ        1276812 Need to use TempObjs and TempRefs
  52.                                     for exception safety and to avoid TRY
  53.                                     blocks, 1276807 Opt./Bug: use StdTypIO
  54.                                     routines for portable streaming & smaller
  55.                                     footprint, 1276806 Optimization: use
  56.                                     kODFalse instead of kODTrue in comparisons
  57.         <64>      8/3/95    RR        #1257260: Collapse B classes. Remove
  58.                                     somInit methods. Don't call IsInitialized
  59.                                     or SubclassResponsibility
  60.         <63>      8/2/95    VL        1270320: Correct refcounting in
  61.                                     SetCurrentMenuBar and SetBaseMenuBar.
  62.         <62>     6/30/95    RR        1242642 BB Ref counting fixes in
  63.                                     HideODWindow.
  64.         <61>     6/28/95    RR        1242642 BB Mostly ref counting. AddWindow
  65.                                     and RemoveWindow adjust ref counts. Window
  66.                                     iterator skips items marked for lazy
  67.                                     deletion.
  68.         <60>     6/26/95    TÇ        1242642 BB:Fix refcounting bugs
  69.         <59>     6/25/95    TÇ        1242642 BB: Turn on ODDebug warning if
  70.                                     refcount is wrong in
  71.                                     ODRefCntObjectsomUninit.
  72.         <58>     6/22/95    RR        #1245283 Undoable frame deletion
  73.                                     #1209427 Changed private api between
  74.                                     iterator and iteratee. Allow deletion while
  75.                                     iterating
  76.         <57>     6/19/95    jpa        Added hook to check for path pop-up
  77.                                     (cmd-click title bar) [1259398]
  78.         <56>     6/15/95    RR        #1256879 Get->AcquireCurrentMenuBar
  79.         <55>      6/8/95    RR        #1257260 Collapse base classes. #1214898
  80.                                     StdTypes.r -> ODTypes.r
  81.         <54>     5/31/95    RR        #1251403 Release after AcquirePart #1251980
  82.                                     Missing release in GetFrontRootWindow
  83.         <53>     5/26/95    RR        #1251403: Multithreading naming support
  84.         <52>     5/25/95    jpa        List.h --> LinkList.h [1253324]
  85.         <51>     5/17/95    RR        #1250135/1250137/1250143 Getters increment
  86.                                     refcount
  87.         <50>     5/10/95    RR        # 1234319. Check for rootFrameList before
  88.                                     internalizing
  89.         <49>      5/4/95    eeh        1242889: get drafts string from resource
  90.         <48>      5/2/95    RR        # 1244133 Fixed SetDefaultWindowTitles to
  91.                                     avoid extra bogus characters
  92.         <47>     4/28/95    RR        1211085 Remove 5$ comments
  93.         <46>     4/14/95    TÇ        With RR & CG: #1194507 DR/BB:title bar of a
  94.                                     draft window doesn't reveal it is a draft
  95.                                     or which draft it is
  96.         <45>     4/13/95    RR        #1216618 Added ODVolatile
  97.         <44>      4/7/95    RR        #1216618 Added SOM_TRY etc.
  98.         <43>      4/6/95    RR        # 1236361 Call Deactivate in HideODWindow.
  99.                                     Remove redundant code to prevent
  100.                                     deadstripping of PlatformFile
  101.         <42>      4/4/95    RR        # 1220104 Use ODObjectsAreEqual
  102.         <41>     3/22/95    RR        #1225420, 1227993 Parts internalize
  103.                                     windows. Modified OpenWindow, Externalize,
  104.                                     Internalize. Added RegisterWindowForFrame
  105.         <40>     3/10/95    RR        # 1225861 Send Suspend/resume to invisible
  106.                                     windows
  107.         <39>      3/7/95    RR        # 1151165 Cleaned up AdjustPartMenus #
  108.                                     1220929 Added fMenuFocus
  109.         <38>      3/3/95    CC        # 1205622: Ensure activate event is
  110.                                     delivered after modal dialog is dismissed.
  111.         <37>      3/1/95    RR        # 1205622 ::OpenWindows now supports
  112.                                     re-opening an open draft by bringing its
  113.                                     windows to the front.
  114.         <36>     2/24/95    jpa        Use ODNewRgn. [1220810]
  115.         <35>     2/22/95    RR        # 1213850 Call AdjustMenus for root part of
  116.                                     active window before calling it for menu
  117.                                     focus
  118.         <34>     2/20/95    TÇ        #1221861 BB: Incomplete AOCE support needs
  119.                                     to be removed from OpenDoc
  120.         <33>     1/31/95    RR        # 1209165 Rewrote HandleAOCEEvent. #1209552
  121.                                     Call SendBehind in HideODWindow
  122.         <31>     1/26/95    VL        #???: Use updated Storage Unit Ref API.
  123.         <30>     1/25/95    RR        #1211853 Removed session parameter from
  124.                                     CreateMenuBar. Pass _fSession to
  125.                                     InitMenuBar
  126.         <29>     1/23/95    RR        # 1211853 Added CreateMenuBar
  127.         <28>      1/4/95    eeh        1209165: added test to
  128.                                     HandleAOCEMailerEvent
  129.         <27>    12/20/94    VL        1195012: Make Storage calls be
  130.                                     marshallable.
  131.         <26>    12/19/94    eeh        1192626: change ::Internalize not to
  132.                                     duplicate windows already open
  133.         <25>    11/28/94    RR        Check for AOCE presence
  134.         <24>     11/1/94    RR        #1196761 Don't exit HandleAOCEMailerEvent
  135.                                     without handling updates in inactive mailer
  136.                                     windows
  137.         <23>    10/18/94    RR        Used AcquireWindow(id) to validate windows in
  138.                                     CLoseWindows, in case part closed
  139.                                     subsidiary windows
  140.         <22>     9/29/94    RA        1189812: Mods for 68K build.
  141.         <21>     9/23/94    VL        1155579, 1184272: Use StorUtil to
  142.                                     create/get container and its file.
  143.         <20>     9/22/94    eeh        #1154961 AddAOCEMailer takes additional
  144.                                     param.
  145.         <19>     9/19/94    eeh        #1164891: check for userCanceledErr after
  146.                                     SMPMailerEvent call.
  147.         <18>      9/1/94    RR        #1176805 Release old base menu bar
  148.         <17>      9/1/94    CC        RADAR #1181971 - missing factory methods
  149.                                     (for JBS)
  150.         <16>     8/29/94    RR        #1171772 DOn't call SelectWindow
  151.         <15>     8/26/94    TÇ        #1181761 rename obsolete kOD IDs to correct
  152.                                     kODStrong/WeakStorageUnitRefs
  153.         <14>     8/26/94    VL        1183174: Use updated cloning APIs.
  154.         <13>     8/25/94    RR        Added private AcquireBaseMenuBar. Set
  155.                                     generation of menubar in SetBaseMenuBar
  156.         <12>     8/19/94    TÇ        #1180922 Need to Stop using obsolete types
  157.                                     (kOD ID)
  158.         <11>     8/18/94    jpa        Filled in CreateCanvas [1180387]
  159.         <10>     8/16/94    JBS        1180387: add CreateCanvas()
  160.          <9>     8/15/94    JBS        1181138: add frameType to CreateFrame();
  161.                                     1181156: UI API Cleanup
  162.          <8>      8/3/94    VL        1153123: Storage to ODStor.
  163.          <7>     7/27/94    eeh        fix use of Point and Rect (honesty to SOM…)
  164.          <6>     7/21/94    eeh        fix FixUpMailerWindow
  165.          <5>     7/15/94    TÇ        make sure PlatformFile code is not
  166.                                     deadstripped
  167.          <4>      7/8/94    RR        Converted HandleAOCEMailerEvent
  168.          <3>     6/27/94    eeh        add Environment* parameters to
  169.                                     AOCEHelperObj method calls
  170.          <2>     9/27/94    RR        Call InitBaseWindowState
  171.          <1>     9/26/94    RR        first checked in
  172.  
  173.     To Do:
  174.     In Progress:
  175.         
  176. */
  177.  
  178.  
  179. #define ODWindowState_Class_Source
  180. #define VARIABLE_MACROS
  181. #include <WinStat.xih>
  182.  
  183. #ifndef SOM_ODWindowIterator_xh
  184. #include <WinIter.xh>
  185. #endif
  186.  
  187. #ifndef _WINUTILM_
  188. #include "WinUtilM.h" 
  189. #endif
  190.  
  191. #ifndef _UIDEFS_
  192. #include "UIDefs.h"
  193. #endif
  194.  
  195. #ifndef _TEMPOBJ_
  196. #include <TempObj.h>
  197. #endif
  198.  
  199. #ifndef _STDTYPIO_
  200. #include <StdTypIO.h>
  201. #endif
  202.  
  203. #ifndef SOM_ODSession_xh
  204. #include <ODSessn.xh>
  205. #endif
  206.  
  207. #ifndef SOM_ODWindow_xh
  208. #include <Window.xh>
  209. #endif
  210.  
  211. #ifndef SOM_ODMenuBar_xh
  212. #include <MenuBar.xh>
  213. #endif
  214.  
  215. #ifndef SOM_ODArbitrator_xh
  216. #include <Arbitrat.xh>
  217. #endif
  218.  
  219. #ifndef SOM_Module_Apple_defined
  220. #include <Part.xh>
  221. #endif
  222.  
  223. #ifndef SOM_ODFrame_xh
  224. #include <Frame.xh>
  225. #endif
  226.  
  227. #ifndef SOM_ODFacet_xh
  228. #include <Facet.xh>
  229. #endif
  230.  
  231. #ifndef SOM_ODCanvas_xh
  232. #include <Canvas.xh>
  233. #endif
  234.  
  235. #ifndef SOM_ODDraft_xh
  236. #include <Draft.xh>
  237. #endif
  238.  
  239. #ifndef SOM_ODDocument_xh
  240. #include <Document.xh>
  241. #endif
  242.  
  243. #ifndef SOM_ODContainer_xh
  244. #include <ODCtr.xh>
  245. #endif
  246.  
  247. #ifndef SOM_ODStorageSystem_xh
  248. #include <ODStor.xh>
  249. #endif
  250.  
  251. #ifndef SOM_ODStorageUnit_xh
  252. #include <StorageU.xh>
  253. #endif
  254.  
  255. #ifndef SOM_Module_OpenDoc_Commands_defined
  256. #include <CmdDefs.xh>
  257. #endif
  258.  
  259. #ifndef __GESTALTEQU__
  260. #include <GestaltEqu.h>
  261. #endif
  262.  
  263. #ifndef _DLOGUTIL_
  264. #include <DlogUtil.h>
  265. #endif
  266.  
  267. #ifndef _USERSRCM_
  268. #include <UseRsrcM.h>
  269. #endif
  270.  
  271. #ifndef _PLFMFILE_
  272. #include <PlfmFile.h>
  273. #endif
  274.  
  275. #ifndef _PASCLSTR_
  276. #include "PasclStr.h"
  277. #endif
  278.  
  279. #ifndef _LINKLIST_
  280. #include <LinkList.h>
  281. #endif
  282.  
  283. #ifndef _ORDCOLL_
  284. #include "OrdColl.h"
  285. #endif
  286.  
  287. #ifndef _EXCEPT_
  288. #include "Except.h"
  289. #endif
  290.  
  291. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  292. #include <StdTypes.xh>
  293. #endif
  294.  
  295. #ifndef SOM_Module_OpenDoc_StdProps_defined
  296. #include <StdProps.xh>
  297. #endif
  298.  
  299. #ifndef SOM_Module_OpenDoc_Foci_defined
  300. #include <Foci.xh>
  301. #endif
  302.  
  303. #ifndef _ODUTILS_
  304. #include <ODUtils.h>
  305. #endif
  306.  
  307. #ifndef _STORUTIL
  308. #include <StorUtil.h>
  309. #endif
  310.  
  311. #ifndef __LOWMEM__
  312. #include <LowMem.h> // For WindowList global
  313. #endif
  314.  
  315. #ifndef __TOOLUTILS__
  316. #include <ToolUtils.h>
  317. #endif
  318.  
  319. #ifndef _ODDEBUG_
  320. #include "ODDebug.h"    // Adkins -- added
  321. #endif
  322.  
  323. #ifndef _WINPOPM_
  324. #include "WinPopM.h"
  325. #endif
  326.  
  327.  
  328. // New Window API uses a new "WindowRef" type as an opaque window type. So that we can compile
  329. // with or without the new Windows.h, define WindowRef if it's not already defined:      --jpa
  330. #ifndef STRICT_WINDOWS
  331. #define WindowRef WindowPeek
  332. #endif
  333.  
  334. #define ODDebugActivates 0
  335.  
  336. #pragma segment ODWindowState
  337.  
  338. #include "WinStatB.cpp"    // Platform-independent methods, if any
  339.  
  340. static ODBoolean IsFrontProcess()
  341. {
  342.     ProcessSerialNumber    currentPSN;
  343.     ProcessSerialNumber    frontPSN;
  344.     OSErr                getFrontProcessResult;
  345.     OSErr                getCurrentProcessResult;
  346.     ODBoolean                isSameProcess = kODFalse;
  347.     
  348.     // Compare this process and the front process
  349.     getFrontProcessResult = GetFrontProcess(&frontPSN);
  350.     getCurrentProcessResult = GetCurrentProcess(¤tPSN);
  351.     
  352.     if ((getFrontProcessResult == noErr) && (getCurrentProcessResult == noErr))
  353.         SameProcess(&frontPSN, ¤tPSN, &isSameProcess);
  354.         
  355.     return isSameProcess;
  356. }
  357.  
  358.  
  359. SOM_Scope void  SOMLINK ODWindowStateDeactivateFrontWindows(ODWindowState *somSelf, Environment *ev)
  360. {
  361.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  362.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateDeactivateFrontWindows");
  363.     
  364.     SOM_TRY
  365.  
  366.         WindowPtr            firstDocWindow;
  367.         WindowPtr            secondDocWindow;
  368.         WindowPtr            window;
  369.         WindowListIterator    iter;
  370.     
  371.         firstDocWindow = somSelf->GetFrontNonFloatingPlatformWindow(ev);
  372.         if (firstDocWindow != kODNULL)
  373.             secondDocWindow = GetNextWindow(firstDocWindow);
  374.         
  375.         window = iter.First();
  376.         while (iter.IsNotComplete() && (window != secondDocWindow)) 
  377.         {
  378.             if (GetWindowVisible(window) != kODFalse) 
  379.             {
  380.                 somSelf->DeactivateWindow(ev,window);
  381.             }
  382.             window = iter.Next();
  383.         }
  384.         
  385.     SOM_CATCH_ALL
  386.     SOM_ENDTRY
  387. }
  388.  
  389. SOM_Scope void  SOMLINK ODWindowStateActivateFrontWindows(ODWindowState *somSelf, Environment *ev)
  390. {
  391.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  392.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateActivateFrontWindows");
  393.  
  394.     SOM_TRY
  395.     
  396.         WindowPtr            firstDocWindow;
  397.         WindowPtr            secondDocWindow;
  398.         WindowPtr            window;
  399.         WindowListIterator    iter;
  400.         
  401.         somSelf->RepairWindowOrder( ev );
  402.  
  403.         firstDocWindow = somSelf->GetFrontNonFloatingPlatformWindow(ev);
  404.         if (firstDocWindow != kODNULL)
  405.             secondDocWindow = GetNextWindow(firstDocWindow);
  406.         
  407.         window = iter.First();
  408.         while (iter.IsNotComplete() && (window != secondDocWindow)) 
  409.         {
  410.             if (GetWindowVisible(window) != kODFalse) 
  411.             {
  412.                 somSelf->ActivateWindow(ev,window);
  413.             }
  414.             window = iter.Next();
  415.         }
  416.  
  417.     SOM_CATCH_ALL
  418.     SOM_ENDTRY
  419. }
  420.  
  421. SOM_Scope ODWindow*  SOMLINK ODWindowStateAcquireFrontWindow(ODWindowState *somSelf, Environment *ev)
  422. {
  423.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  424.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateAcquireFrontWindow");
  425.  
  426.     ODWindow*    odWindow = kODNULL;
  427.  
  428.     SOM_TRY
  429.  
  430.         WindowPtr window = FrontWindow();
  431.         
  432.         if (window != kODNULL) 
  433.         {
  434.             if (somSelf->IsODWindow(ev,window))
  435.                 odWindow = somSelf->AcquireODWindow(ev,window);
  436.         }
  437.  
  438.     SOM_CATCH_ALL
  439.     SOM_ENDTRY
  440.         
  441.     // AcquireODWindow increments ref count
  442.     //if (odWindow)
  443.     //    odWindow->Acquire(ev);    
  444.     return odWindow;
  445. }
  446.  
  447. SOM_Scope ODWindow*  SOMLINK ODWindowStateAcquireFrontFloatingWindow(ODWindowState *somSelf, Environment *ev)
  448. {
  449.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  450.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateAcquireFrontFloatingWindow");
  451.  
  452.     ODWindow* frontFloatingWindow = kODNULL;
  453.     
  454.     SOM_TRY
  455.     
  456.         WindowListIterator    iter;
  457.         
  458.         WindowPtr    platformWindow = iter.First();
  459.         while (iter.IsNotComplete() && (frontFloatingWindow == kODNULL)) 
  460.         {
  461.             ODWindow*    odWindow = somSelf->AcquireODWindow(ev,platformWindow);
  462.             if (odWindow != kODNULL) 
  463.             {
  464.                 if (odWindow->IsFloating(ev) != kODFalse) 
  465.                 {
  466.                     frontFloatingWindow = odWindow;
  467.                 }
  468.                 else
  469.                 {
  470.                     ODReleaseObject(ev, odWindow);    // -- TÇ: released only if we don't want it.
  471.                 }
  472.             }
  473.         }
  474.  
  475.     SOM_CATCH_ALL
  476.     
  477.         frontFloatingWindow = kODNULL;
  478.         
  479.     SOM_ENDTRY
  480.  
  481.     // AcquireODWindow increments ref count
  482.     //if (frontFloatingWindow)
  483.     //    frontFloatingWindow->Acquire(ev);
  484.     return frontFloatingWindow;
  485. }
  486.  
  487. SOM_Scope ODWindow*  SOMLINK ODWindowStateAcquireFrontRootWindow(ODWindowState *somSelf, Environment *ev)
  488. {
  489.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  490.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateAcquireFrontRootWindow");
  491.  
  492.     ODWindow* odWindow = kODNULL;
  493.  
  494.     SOM_TRY
  495.  
  496.         WindowListIterator    iter;
  497.         
  498.         for (WindowPtr platformWindow = iter.First(); 
  499.             iter.IsNotComplete(); 
  500.             platformWindow = iter.Next())
  501.         {
  502.             odWindow = somSelf->AcquireODWindow(ev,platformWindow);
  503.             if (odWindow && odWindow->IsRootWindow(ev))
  504.                 break;
  505.             else
  506.                 ODReleaseObject(ev, odWindow);                
  507.         }
  508.  
  509.     SOM_CATCH_ALL
  510.     
  511.         odWindow = kODNULL;
  512.         
  513.     SOM_ENDTRY
  514.  
  515.     // AcquireODWindow increments ref count
  516.     //if (odWindow)
  517.     //    odWindow->Acquire(ev);
  518.     return odWindow;    // -- TÇ: was acquired in the for loop above.
  519. }
  520.  
  521. SOM_Scope void  SOMLINK ODWindowStateInitWindowState(ODWindowState *somSelf, Environment *ev,
  522.         ODSession* session)
  523. {
  524.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  525.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateInitWindowState");
  526.  
  527.     LinkedList* linkedList = kODNULL; ODVolatile(linkedList);
  528.     
  529.     SOM_TRY
  530.     
  531.         /* Moved from somInit. SOM itself sets fields to zero
  532.         _fWindowList = kODNULL;
  533.         _fSession = kODNULL;
  534.         _fBaseMenuBar = kODNULL;
  535.         _fCurrentMenuBar = kODNULL;
  536.         _fNextID = 0;
  537.         _fMenuFocus = 0;
  538.         _fIteratorCount = 0;
  539.         */
  540.         
  541.         somSelf->InitObject(ev);    
  542.         _fSession = session;
  543.         _fMenuFocus = _fSession->Tokenize(ev,kODMenuFocus);
  544.         linkedList = new LinkedList;
  545.         _fWindowList = linkedList;
  546.     
  547.     SOM_CATCH_ALL
  548.     
  549.         ODDeleteObject(linkedList);
  550.         
  551.     SOM_ENDTRY
  552. }
  553.  
  554. SOM_Scope void  SOMLINK ODWindowStateSetCurrentMenuBar(ODWindowState *somSelf, Environment *ev,
  555.         ODMenuBar* theMenuBar)
  556. {
  557.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  558.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateSetCurrentMenuBar");
  559.  
  560.     SOM_TRY
  561.  
  562.         if (!ODObjectsAreEqual(ev, _fCurrentMenuBar, theMenuBar))
  563.         {
  564.             ODReleaseObject(ev, _fCurrentMenuBar);
  565.             if (theMenuBar)
  566.                 theMenuBar->Acquire(ev);
  567.             _fCurrentMenuBar = theMenuBar;
  568.         }
  569.  
  570.     SOM_CATCH_ALL
  571.     SOM_ENDTRY
  572. }
  573.  
  574. SOM_Scope ODMenuBar*  SOMLINK ODWindowStateAcquireCurrentMenuBar(ODWindowState *somSelf, Environment *ev)
  575. {
  576.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  577.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateGetCurrentMenuBar");
  578.  
  579.     SOM_TRY
  580.     
  581.     if (_fCurrentMenuBar)
  582.         _fCurrentMenuBar->Acquire(ev);
  583.     
  584.     SOM_CATCH_ALL
  585.     SOM_ENDTRY
  586.     return _fCurrentMenuBar;
  587. }
  588.  
  589. SOM_Scope ODMenuBar*  SOMLINK ODWindowStateAcquireBaseMenuBar(ODWindowState *somSelf, Environment *ev)
  590. {
  591.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  592.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateAcquireBaseMenuBar");
  593.  
  594.     SOM_TRY
  595.     
  596.     if (_fBaseMenuBar)
  597.         _fBaseMenuBar->Acquire(ev);
  598.     
  599.     SOM_CATCH_ALL
  600.     SOM_ENDTRY
  601.     
  602.     return _fBaseMenuBar;
  603. }
  604.  
  605. SOM_Scope ODWindow*  SOMLINK ODWindowStateAddWindow(ODWindowState *somSelf, Environment *ev,
  606.         ODWindow* window)
  607. {
  608.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  609.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateAddWindow");
  610.  
  611.     SOM_TRY
  612.  
  613.         if (window)
  614.         {
  615.             ODBoolean found = kODFalse;
  616.             WindowLink* foundLink = kODNULL;
  617.         
  618.             LinkedListIterator iter(_fWindowList);
  619.             
  620.             for ( WindowLink* link = (WindowLink*) iter.First();
  621.                     iter.IsNotComplete(); 
  622.                     link = (WindowLink*) iter.Next())
  623.             {
  624.                 if (!link->ShouldRemove() && ODObjectsAreEqual(ev, link->fWindow, window))
  625.                 {
  626.                     found = kODTrue;
  627.                     foundLink = link;
  628.                     break;                
  629.                 }
  630.             }
  631.             if (!found)
  632.             {
  633.                 // There is a problem here. We assume that the window is always going to be
  634.                 // in front. We may need to change the Window API to handle the case when
  635.                 // someone actually wants a window at the back.
  636.                 
  637.                 WindowPtr    platformWindow = window->GetPlatformWindow(ev);
  638.                 WindowPtr    lastFloatingWindow = somSelf->GetLastFloatingPlatformWindow(ev);
  639.                 if (lastFloatingWindow != kODNULL) {
  640.                     SendBehind(platformWindow, lastFloatingWindow);
  641.                 }
  642.                 else {
  643.                     BringToFront(platformWindow);
  644.                 }
  645.                 
  646.                 window->Acquire(ev);
  647.                 _fNextID++;
  648.                 WindowLink* link = new WindowLink(_fNextID, window);
  649.                 window->SetID(ev,_fNextID);
  650.                 THROW_IF_NULL(link);
  651.                 _fWindowList->AddLast(link);
  652.             }
  653.         }
  654.  
  655.     SOM_CATCH_ALL
  656.     
  657.         window = kODNULL;
  658.         
  659.     SOM_ENDTRY
  660.  
  661.     return window;
  662. }
  663.  
  664. SOM_Scope void  SOMLINK ODWindowStateRemoveWindow(ODWindowState *somSelf, Environment *ev,
  665.         ODWindow* oldWindow)
  666. {
  667.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  668.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateRemoveWindow");
  669.  
  670.     SOM_TRY
  671.     
  672.         ODBoolean found = kODFalse;
  673.         WindowLink* foundLink = kODNULL;
  674.     
  675.         LinkedListIterator iter(_fWindowList);
  676.         
  677.         for ( WindowLink* link = (WindowLink*) iter.First();
  678.                 iter.IsNotComplete(); 
  679.                 link = (WindowLink*) iter.Next())
  680.         {
  681.             if (!link->ShouldRemove() && ODObjectsAreEqual(ev, link->fWindow, oldWindow))
  682.             {
  683.                 found = kODTrue;
  684.                 foundLink = link;
  685.                 break;                
  686.             }
  687.         }
  688.         if (found)
  689.         {
  690.             ODWindow* window = foundLink->fWindow;
  691.             ODReleaseObject(ev, window);
  692.             if (_fIteratorCount > 0)
  693.             {
  694.                 foundLink->fRemove = kODTrue;
  695.             }
  696.             else
  697.             {
  698.                 _fWindowList->Remove(*foundLink);
  699.                 ODDeleteObject(foundLink);
  700.             }
  701.         }
  702.         
  703.     SOM_CATCH_ALL
  704.     SOM_ENDTRY
  705. }
  706.  
  707. SOM_Scope ODWindow*  SOMLINK ODWindowStateFindODWindow(ODWindowState *somSelf, Environment *ev,
  708.         Point* globalPoint)
  709. {
  710.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  711.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateFindODWindow");
  712.  
  713.     ODWindow* odWindow = kODNULL;
  714.     
  715.     SOM_TRY
  716.     
  717.         WindowPtr window;
  718.         FindWindow(*globalPoint, &window);
  719.         if (window)
  720.             odWindow = somSelf->AcquireODWindow(ev,window);
  721.  
  722.     SOM_CATCH_ALL
  723.     SOM_ENDTRY
  724.     
  725.     return odWindow;    // -- TÇ: ODWindowStateFindODWindow is an 'acquire' function
  726. }
  727.  
  728. SOM_Scope void  SOMLINK ODWindowStateReleaseWindow(ODWindowState *somSelf, Environment *ev,
  729.         ODWindow* window)
  730. {
  731.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  732.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateReleaseWindow");
  733.  
  734.     SOM_TRY
  735.  
  736.         ODDeleteObject(window);
  737.  
  738.     SOM_CATCH_ALL
  739.     SOM_ENDTRY
  740. }
  741.  
  742. SOM_Scope void  SOMLINK ODWindowStateSuspendResume(ODWindowState *somSelf, Environment *ev,
  743.         ODEventData* event)
  744. {
  745.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  746.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateSuspendResume");
  747.  
  748.     SOM_TRY
  749.     
  750.         const short kResumeMask = 0x01;    // High byte suspend/resume event 
  751.         
  752.         ODBoolean    goingToBackground = (event->message & kResumeMask) == 0;
  753.         // WindowPtr    frontWindow = somSelf->GetFrontNonFloatingPlatformWindow(ev);
  754.         //ODWindow* odWindow = kODNULL;
  755.  
  756.     #if ODDebug && ODDebugActivates
  757.         somPrintf("WindowState Suspend/Resume %d\n", !goingToBackground);
  758.     #endif
  759.             
  760.         ODWindowIterator* iter = somSelf->CreateWindowIterator(ev);
  761.         
  762.         for (ODWindow* window = iter->First(ev); iter->IsNotComplete(ev); window = iter->Next(ev))
  763.         {
  764.             window->SuspendResume(ev,event);
  765.         }
  766.         ODDeleteObject(iter);
  767.         
  768.         // Deactivate the front doc window and any floaters that haven't been hidden. 
  769.         // The system only unhilites the frontmost window
  770.  
  771.         if (goingToBackground)
  772.         {
  773.     #if ODDebug && ODDebugActivates
  774.         somPrintf("WindowState Suspend Event - deactivate front windows\n");
  775.     #endif
  776.             somSelf->DeactivateFrontWindows(ev);
  777.         }
  778.         else
  779.         {
  780.     #if ODDebug && ODDebugActivates
  781.         somPrintf("WindowState Resume Event - activate front windows\n");
  782.     #endif
  783.             somSelf->ActivateFrontWindows(ev);
  784.         }
  785.  
  786.     SOM_CATCH_ALL
  787.     SOM_ENDTRY
  788. }
  789.  
  790. SOM_Scope void  SOMLINK ODWindowStateSelectODWindow(ODWindowState *somSelf, Environment *ev,
  791.         ODWindow* window)
  792. {
  793.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  794.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateSelectODWindow");
  795.  
  796.     SOM_TRY
  797.     
  798.         WindowPtr            currentFrontWindow;
  799.         WindowPtr            lastFloatingWindow;
  800.         Boolean                isFloatingWindow;
  801.         Boolean                isFrontProcess;
  802.         WindowPtr            windowToSelect = window->GetPlatformWindow(ev);
  803.  
  804.         isFrontProcess = IsFrontProcess();
  805.     
  806.         if (window->IsFloating(ev) != kODFalse) 
  807.         {
  808.             isFloatingWindow = kODTrue;
  809.             currentFrontWindow = (WindowPtr) FrontWindow();
  810.         }
  811.         else 
  812.         {
  813.             isFloatingWindow = kODFalse;
  814.             currentFrontWindow = somSelf->GetFrontNonFloatingPlatformWindow(ev);
  815.             lastFloatingWindow = somSelf->GetLastFloatingPlatformWindow(ev);
  816.         }
  817.     
  818.         // Be fast (and lazy) and do nothing if we don’t have to.
  819.         // The !IsActive test was added because this method might get called when
  820.         // in the background during a Drop.
  821.     
  822.         if ((currentFrontWindow != windowToSelect) || (!window->IsActive(ev)))
  823.         {
  824.     
  825.         // Selecting floating windows are easy, since they’re always active
  826.     
  827.             if (isFloatingWindow) 
  828.             {
  829.                 BringToFront(windowToSelect);
  830.             }
  831.             else 
  832.             {
  833.                 // This replaces the code below.
  834.                 // In order to facilitate a predictable flow of events,
  835.                 // we must use Macintosh Toolbox calls that don't generate activate
  836.                 // events themselves (ie. BringToFront, SendBehind). 
  837.                 
  838.                 if (isFrontProcess)
  839.                     somSelf->DeactivateWindow(ev, currentFrontWindow);
  840.                 
  841.                 if (lastFloatingWindow == kODNULL)
  842.                     BringToFront(windowToSelect);
  843.                 else
  844.                     SendBehind(windowToSelect, lastFloatingWindow);
  845.                     
  846.                 //if (isFrontProcess) // Must allow activates for Drop in inactive window 
  847.                     somSelf->ActivateWindow(ev,windowToSelect);    
  848.     
  849.             }
  850.         }
  851.  
  852.     SOM_CATCH_ALL
  853.     SOM_ENDTRY
  854. } // SelectODWindow
  855.  
  856.  
  857. SOM_Scope void  SOMLINK ODWindowStateDragODWindow(ODWindowState *somSelf, Environment *ev,
  858.         ODWindow* window,
  859.         Point* startPoint,
  860.         Rect* draggingBounds)
  861. {
  862.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  863.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateDragODWindow");
  864.  
  865.     SOM_TRY
  866.     
  867.         // Check for command-click on window title:
  868.         if( TrackWindowPathPopUp(ev,window,*startPoint) )
  869.             return;
  870.     
  871.         WindowPtr    windowToDrag = window->GetPlatformWindow(ev);
  872.         Rect        dragRect;
  873.         KeyMap        keyMap;
  874.         GrafPtr        savePort;
  875.         GrafPtr        windowManagerPort;
  876.         RgnHandle    dragRegion;
  877.         RgnHandle    windowContentRegion;
  878.         long        dragResult;
  879.         short        topLimit;
  880.         short        newHorizontalWindowPosition;
  881.         short        newVerticalWindowPosition;
  882.         short        horizontalOffset;
  883.         short        verticalOffset;
  884.         Boolean        commandKeyDown = kODFalse;
  885.         
  886.         // Set up the Window Manager port.
  887.         GetPort(&savePort);
  888.         GetWMgrPort(&windowManagerPort);
  889.         SetPort(windowManagerPort);
  890.         SetClip(GetGrayRgn());
  891.         
  892.         // Check to see if the command key is down.  If it is, don’t bring the window to the
  893.         // front after the move.
  894.         GetKeys(keyMap);
  895.         if (keyMap[1] & 0x8000)
  896.             commandKeyDown = kODTrue;
  897.     
  898.         if (WaitMouseUp())
  899.         {
  900.         
  901.             // Adjust the top of the dragging rectangle so that it’s below the menu bar
  902.             topLimit = LMGetMBarHeight() + 4;
  903.             dragRect = *draggingBounds;
  904.             if (dragRect.top < topLimit)
  905.                 dragRect.top = topLimit;
  906.         
  907.             if ((commandKeyDown != kODFalse) || (window->IsFloating(ev) == kODFalse)) 
  908.             {
  909.                 
  910.                 if (commandKeyDown == kODFalse)
  911.                     // If there are floating windows, clip the dragging outline to draw behind the floaters.
  912.                     /* Adkins -- changed WindowPeek to WindowRef */
  913.                     ClipAbove((WindowRef) somSelf->GetFrontNonFloatingPlatformWindow(ev));
  914.                 else
  915.                     // If the command key was down, clip the outline to draw behind any windows above
  916.                     // the window being dragged.
  917.                     ClipAbove((WindowRef) windowToDrag); /* Adkins -- changed WindowPeek to WindowRef */
  918.     
  919.             }
  920.                 
  921.             // Create a region to drag
  922.             dragRegion = ODNewRgn();
  923.             CopyRgn(GetStructureRegion(windowToDrag), dragRegion);
  924.             
  925.             // Drag the window around
  926.             dragResult = DragGrayRgn(dragRegion, *startPoint, &dragRect, &dragRect, noConstraint, nil);
  927.         
  928.             // Restore the port right now for coordinate conversion.
  929.             SetPort(savePort);
  930.     
  931.             if (dragResult != 0) 
  932.             {
  933.                 horizontalOffset = (ODSShort) (dragResult & 0xFFFF);
  934.                 verticalOffset = (ODSShort) (dragResult >> 16);
  935.         
  936.                 // Only move it if it stayed inside the dragging box.
  937.                 if (verticalOffset != -32768) 
  938.                 {
  939.                     windowContentRegion = GetContentRegion(windowToDrag);
  940.                     newHorizontalWindowPosition = (**windowContentRegion).rgnBBox.left + horizontalOffset;
  941.                     newVerticalWindowPosition = (**windowContentRegion).rgnBBox.top + verticalOffset;
  942.                     
  943.                     MoveWindow((WindowPtr) windowToDrag, newHorizontalWindowPosition, newVerticalWindowPosition, kODFalse);
  944.                     
  945.                 }
  946.             }
  947.         
  948.             // Get rid of the dragging region
  949.             DisposeRgn(dragRegion);
  950.         }
  951.  
  952.         // Restore the port
  953.         SetPort(savePort);
  954.  
  955.         // Bring the window forward if the command key wasn’t down
  956.         if (commandKeyDown == kODFalse)
  957.             somSelf->SelectODWindow(ev, window);
  958.     
  959.     SOM_CATCH_ALL
  960.     SOM_ENDTRY
  961. }
  962.  
  963. SOM_Scope void  SOMLINK ODWindowStateShowODWindow(ODWindowState *somSelf, Environment *ev,
  964.         ODWindow* window)
  965. {
  966.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  967.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateShowODWindow");
  968.  
  969.     SOM_TRY
  970.     
  971.         WindowPtr            windowToShow = window->GetPlatformWindow(ev);
  972.         WindowPtr            windowBehind;
  973.         ODBoolean            windowIsInFront = kODFalse;
  974.         ODBoolean            isFrontProcess = IsFrontProcess();
  975.  
  976.         if (GetWindowVisible(windowToShow) == kODFalse) 
  977.         {
  978.                     
  979.             // If the window behind the window to show is currently the frontmost document window,
  980.             // unhighlight it, and highlight the new front window.
  981.             
  982.             if (window->IsFloating(ev) == kODFalse) 
  983.             {
  984.                 WindowPtr    frontPlatformWindow = somSelf->GetFrontNonFloatingPlatformWindow(ev); 
  985.                 if (frontPlatformWindow == kODNULL)
  986.                     windowIsInFront = kODTrue;
  987.                 else {
  988.                     windowBehind = GetNextWindow(windowToShow);
  989.                     if (windowBehind == frontPlatformWindow) 
  990.                     {
  991.                         if (windowBehind != kODNULL)
  992.                             somSelf->DeactivateWindow(ev,windowBehind);
  993.                         windowIsInFront = kODTrue;
  994.                     }
  995.                 }
  996.             }
  997.             else 
  998.             {
  999.             
  1000.                 // A floating window is being shown.  Should check to see if a modal window is up before
  1001.                 // trying to highlight it.
  1002.             
  1003.                 windowIsInFront = kODTrue;
  1004.             }
  1005.             
  1006.             if ( windowIsInFront && isFrontProcess )
  1007.                 SetWindowHilite(windowToShow, kODTrue);
  1008.             else
  1009.                 SetWindowHilite(windowToShow, kODFalse);
  1010.     
  1011.             // Show the window
  1012.             
  1013.             ShowHide(windowToShow, kODTrue);
  1014.             
  1015.             // If this is the new frontmost document window or a floating window, send it an activate event
  1016.             
  1017.             if ( windowIsInFront && isFrontProcess )
  1018.             {
  1019. #if ODDebug && ODDebugActivates
  1020.                 somPrintf("Activate in ShowODWindow for root frame %x\n", window->GetRootFrame(ev));
  1021. #endif
  1022.                 window->Activate(ev);
  1023.             }
  1024.         }
  1025.  
  1026.     SOM_CATCH_ALL
  1027.     SOM_ENDTRY
  1028. }
  1029.  
  1030. // ref-count-neutral static function used in workaround in HideODWindow below
  1031. static ODBoolean IsFloating(Environment* ev, ODWindowState* windowState, ODPlatformWindow win)
  1032. {
  1033.     ODBoolean isFloating = kODFalse;
  1034.     ODWindow* window = windowState->AcquireODWindow(ev,win);
  1035.     if (window)
  1036.         isFloating = window->IsFloating(ev);
  1037.     ODReleaseObject(ev, window);
  1038.     return isFloating;
  1039. }
  1040.  
  1041. SOM_Scope void  SOMLINK ODWindowStateHideODWindow(ODWindowState *somSelf, Environment *ev,
  1042.         ODWindow* window)
  1043. {
  1044.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1045.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateHideODWindow");
  1046.  
  1047.     SOM_TRY
  1048.     
  1049.         WindowPtr            windowToHide = window->GetPlatformWindow(ev);
  1050.         WindowPtr            frontFloater;
  1051.         WindowPtr            frontPlatformWindow;
  1052.         WindowPtr            windowBehind;
  1053.         
  1054.             
  1055.         if (GetWindowVisible(windowToHide) != kODFalse) 
  1056.         {
  1057.         
  1058.             // Get the first visible floating window, if any.
  1059.             
  1060.             frontFloater = (WindowPtr) FrontWindow();
  1061.             
  1062.             TempODWindow ODFrontFloater = somSelf->AcquireODWindow(ev,frontFloater);
  1063.             if ((ODFrontFloater != kODNULL) && (ODFrontFloater->IsFloating(ev) == kODFalse))
  1064.                 frontFloater = nil;
  1065.             
  1066.             // Get the first visible document window, if any.
  1067.             
  1068.             frontPlatformWindow = somSelf->GetFrontNonFloatingPlatformWindow(ev);
  1069.             
  1070.             // Deactivate and Hide the window.
  1071.             somSelf->DeactivateWindow(ev,windowToHide);
  1072.             
  1073.             ShowHide(windowToHide, kODFalse);
  1074.             
  1075.             // If the frontmost floating window is being hidden, move it behind the floating window
  1076.             // behind it, if there is one.
  1077.             
  1078.             if (windowToHide == frontFloater) 
  1079.             {
  1080.                 windowBehind = GetNextWindow(windowToHide);
  1081.                 
  1082.             // Only do the rearrangement if there’s another floating window.
  1083.     
  1084.     //            if ((windowBehind != kODNULL) &&
  1085.     //                (((ODWindowBehind = somSelf->AcquireODWindow(ev,windowBehind)) != kODNULL) &&
  1086.     //                    (ODWindowBehind->IsFloating() != kODFalse))) {
  1087.     //                SetNextWindow(windowToHide, GetNextWindow(windowBehind));
  1088.     //                SetNextWindow(windowBehind, windowToHide);
  1089.     //                SetWindowList(windowBehind);
  1090.     //            }
  1091.             }
  1092.             else 
  1093.             {
  1094.             
  1095.             // If the frontmost document window is behind hidden, send it behind the window
  1096.             // behind it.
  1097.                 TempODWindow        ODWindowBehind = kODNULL;
  1098.             
  1099.                 if (windowToHide == frontPlatformWindow) 
  1100.                 {                
  1101.                     windowBehind = windowToHide;
  1102.                     /* $$$$$ Need to find out why this doesn't work, ref count wise
  1103.                     do 
  1104.                     {
  1105.                         windowBehind = GetNextWindow(windowBehind);
  1106.                         if (somSelf->IsODWindow(ev,windowBehind))
  1107.                         {
  1108.                             ODReleaseObject(ev, ODWindowBehind); // Swapping references inside loop
  1109.                             ODWindowBehind = somSelf->AcquireODWindow(ev,windowBehind);
  1110.                         }
  1111.                         else
  1112.                             ODWindowBehind = kODNULL;
  1113.                     } 
  1114.                     while (windowBehind && 
  1115.                             (((ODWindowBehind == kODNULL) || (ODWindowBehind->IsFloating(ev))) ||
  1116.                               (GetWindowVisible(windowBehind) == kODFalse)));
  1117.                     */
  1118.                     
  1119.                     // Workaround for above loop, to avoid refcounted variable in loop
  1120.                     // Is Floating is an rc-neutral static function above this method
  1121.                     ODBoolean isODWindow = kODFalse;
  1122.                     do 
  1123.                     {
  1124.                         windowBehind = GetNextWindow(windowBehind);
  1125.                         isODWindow = somSelf->IsODWindow(ev,windowBehind);
  1126.                     } 
  1127.                     while (windowBehind && 
  1128.                             (((isODWindow == kODFalse) || (IsFloating(ev, somSelf, windowBehind))) ||
  1129.                               (GetWindowVisible(windowBehind) == kODFalse)));
  1130.                     // End workaround
  1131.                     if (windowBehind != kODNULL) 
  1132.                     {
  1133.                         // Note: Experiment to fix #1209552. Using GetNextVisible instead of GetNext
  1134.                         // might be better
  1135.                         
  1136.                         SendBehind(windowToHide, windowBehind);
  1137.                     
  1138.                         // The window behind it is now the front document window.  Highlight it and send it
  1139.                         // and activate event.
  1140.                         
  1141.                         if (IsFrontProcess())
  1142.                             somSelf->ActivateWindow(ev,windowBehind);
  1143.                     }
  1144.                 }
  1145.  
  1146.             }
  1147.         }
  1148.  
  1149.     SOM_CATCH_ALL
  1150.     SOM_ENDTRY
  1151. }
  1152.  
  1153. /*
  1154.  *  for ODWindowIterator
  1155.  */
  1156.  
  1157. SOM_Scope ODULong  SOMLINK ODWindowStateAddIterator(ODWindowState *somSelf, Environment *ev,
  1158.         ODWindowIterator* iterator)
  1159. {
  1160.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1161.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateAddIterator");
  1162.  
  1163.     LinkedListIterator* iter = kODNULL; ODVolatile(iter);
  1164.  
  1165.     SOM_TRY
  1166.     
  1167.         iter = new LinkedListIterator(_fWindowList);
  1168.         _fIteratorCount++;
  1169.             
  1170.     SOM_CATCH_ALL
  1171.     
  1172.         ODDeleteObject(iter);
  1173.         
  1174.     SOM_ENDTRY
  1175.  
  1176.     return (ODULong) iter;
  1177. }
  1178.  
  1179. SOM_Scope ODWindow*  SOMLINK ODWindowStateFirst(ODWindowState *somSelf, Environment *ev,
  1180.         ODULong iteratorID)
  1181. {
  1182.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1183.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateFirst");
  1184.  
  1185.     ODWindow* window = kODNULL;
  1186.  
  1187.     SOM_TRY
  1188.     
  1189.         LinkedListIterator* iterator = (LinkedListIterator*) iteratorID; 
  1190.         WindowLink* link = (WindowLink*) iterator->First();
  1191.         
  1192.         while (link && link->ShouldRemove())
  1193.             link = (WindowLink*) iterator->Next();
  1194.             
  1195.         if (link)
  1196.             window = link->fWindow;
  1197.  
  1198.     SOM_CATCH_ALL
  1199.     SOM_ENDTRY
  1200.     
  1201.     return window;
  1202. }
  1203.  
  1204. SOM_Scope ODWindow*  SOMLINK ODWindowStateNext(ODWindowState *somSelf, Environment *ev,
  1205.         ODULong iteratorID)
  1206. {
  1207.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1208.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateNext");
  1209.  
  1210.     ODWindow* window = kODNULL;
  1211.  
  1212.     SOM_TRY
  1213.     
  1214.         LinkedListIterator* iterator = (LinkedListIterator*) iteratorID; 
  1215.         WindowLink* link = (WindowLink*) iterator->Next();
  1216.  
  1217.         while (link && link->ShouldRemove())
  1218.             link = (WindowLink*) iterator->Next();
  1219.  
  1220.         if (link)
  1221.             window = link->fWindow;
  1222.  
  1223.     SOM_CATCH_ALL
  1224.     SOM_ENDTRY
  1225.     
  1226.     return window;
  1227. }
  1228.  
  1229. SOM_Scope ODWindow*  SOMLINK ODWindowStateLast(ODWindowState *somSelf, Environment *ev,
  1230.         ODULong iteratorID)
  1231. {
  1232.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1233.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateLast");
  1234.  
  1235.     ODWindow* window = kODNULL;
  1236.  
  1237.     SOM_TRY
  1238.     
  1239.         LinkedListIterator* iterator = (LinkedListIterator*) iteratorID; 
  1240.         WindowLink* link = (WindowLink*) iterator->Last();
  1241.  
  1242.         while (link && link->ShouldRemove())
  1243.             link = (WindowLink*) iterator->Previous();
  1244.  
  1245.         if (link)
  1246.             window = link->fWindow;
  1247.  
  1248.     SOM_CATCH_ALL
  1249.     SOM_ENDTRY
  1250.     
  1251.     return window;
  1252. }
  1253.  
  1254. SOM_Scope ODWindow*  SOMLINK ODWindowStatePrevious(ODWindowState *somSelf, Environment *ev,
  1255.         ODULong iteratorID)
  1256. {
  1257.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1258.     ODWindowStateMethodDebug("ODWindowState","ODWindowStatePrevious");
  1259.  
  1260.     ODWindow* window = kODNULL;
  1261.  
  1262.     SOM_TRY
  1263.     
  1264.         LinkedListIterator* iterator = (LinkedListIterator*) iteratorID; 
  1265.         WindowLink* link = (WindowLink*) iterator->Previous();
  1266.  
  1267.         while (link && link->ShouldRemove())
  1268.             link = (WindowLink*) iterator->Previous();
  1269.  
  1270.         if (link)
  1271.             window = link->fWindow;
  1272.  
  1273.     SOM_CATCH_ALL
  1274.     SOM_ENDTRY
  1275.     
  1276.     return window;
  1277. }
  1278.  
  1279. SOM_Scope ODBoolean  SOMLINK ODWindowStateIsNotComplete(ODWindowState *somSelf, Environment *ev,
  1280.         ODULong iteratorID)
  1281. {
  1282.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1283.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateIsNotComplete");
  1284.     
  1285.     ODBoolean isNotComplete = kODFalse;
  1286.  
  1287.     SOM_TRY
  1288.  
  1289.         LinkedListIterator* iterator = (LinkedListIterator*) iteratorID; 
  1290.         isNotComplete = iterator->IsNotComplete();
  1291.     
  1292.     SOM_CATCH_ALL
  1293.     SOM_ENDTRY
  1294.  
  1295.     return isNotComplete;
  1296. }
  1297.  
  1298. SOM_Scope void  SOMLINK ODWindowStateRemoveIterator(ODWindowState *somSelf, Environment *ev,
  1299.         ODULong iteratorID)
  1300. {
  1301.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1302.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateRemoveIterator");
  1303.  
  1304.     SOM_TRY
  1305.     
  1306.         LinkedListIterator* iterator = (LinkedListIterator*) iteratorID; 
  1307.         ODDeleteObject(iterator);
  1308.         _fIteratorCount--;
  1309.         
  1310.         if (_fIteratorCount == 0) // Clear items marked for deletion during iteration
  1311.         {
  1312.             LinkedListIterator iter(_fWindowList);
  1313.             for ( WindowLink* link = (WindowLink*) iter.First();
  1314.                     iter.IsNotComplete(); 
  1315.                     link = (WindowLink*) iter.Next())
  1316.             {
  1317.                 if (link->ShouldRemove())
  1318.                 {
  1319.                     iter.RemoveCurrent();
  1320.                     delete link;
  1321.                 }
  1322.             }
  1323.         }
  1324.  
  1325.     SOM_CATCH_ALL
  1326.     SOM_ENDTRY
  1327. }
  1328.  
  1329.  
  1330. SOM_Scope void  SOMLINK ODWindowStateActivateWindow(ODWindowState *somSelf, Environment *ev,
  1331.         ODPlatformWindow platformWindow)
  1332. {
  1333.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1334.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateActivateWindow");
  1335.  
  1336.     SOM_TRY
  1337.     
  1338.         somSelf->HighlightAndActivateWindow(ev, platformWindow, kODTrue);
  1339.  
  1340.     SOM_CATCH_ALL
  1341.     SOM_ENDTRY
  1342. }
  1343.  
  1344. SOM_Scope void  SOMLINK ODWindowStateDeactivateWindow(ODWindowState *somSelf, Environment *ev,
  1345.         ODPlatformWindow platformWindow)
  1346. {
  1347.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1348.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateDeactivateWindow");
  1349.  
  1350.     SOM_TRY
  1351.  
  1352.         somSelf->HighlightAndActivateWindow(ev, platformWindow, kODFalse);
  1353.  
  1354.     SOM_CATCH_ALL
  1355.     SOM_ENDTRY
  1356. }
  1357.  
  1358. SOM_Scope void  SOMLINK ODWindowStateHighlightAndActivateWindow(ODWindowState *somSelf, Environment *ev,
  1359.         ODPlatformWindow platformWindow,
  1360.         ODBoolean activate)
  1361. {
  1362.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1363.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateHighlightAndActivateWindow");
  1364.  
  1365.     SOM_TRY
  1366.     
  1367. #if ODDebug && ODDebugActivates
  1368.     somPrintf("Activate/Deactivate message from OpenDoc\n");
  1369. #endif
  1370.  
  1371.         // Note: This optimization doesn't work if we don't dispatch
  1372.         // activate events from the Toolbox. eg. if you dismiss a modal dialog
  1373.         // the activate calls below don't get made because the Toolbox must have already
  1374.         // tweaked the highlighting.
  1375.     
  1376.         //if (AcquireWindowHilite(platformWindow) != activate) 
  1377.         {
  1378.             HiliteWindow( platformWindow, IsFrontProcess() ? activate : kODFalse );
  1379.             
  1380.             if (somSelf->IsODWindow(ev,platformWindow) != kODFalse) 
  1381.             {
  1382.             
  1383.                 TempODWindow odWindow = somSelf->AcquireODWindow(ev,platformWindow);
  1384.                 if (activate == kODFalse)
  1385.                 {
  1386.     #if ODDebug && ODDebugActivates
  1387.                     somPrintf("Deactivate message from OpenDoc for root frame %x\n", odWindow->GetRootFrame(ev));
  1388.     #endif
  1389.                     odWindow->Deactivate(ev);
  1390.                 }
  1391.                 else
  1392.                 {
  1393.     #if ODDebug && ODDebugActivates
  1394.                     somPrintf("Activate message from OpenDoc for root frame %x\n", odWindow->GetRootFrame(ev));
  1395.     #endif
  1396.                     odWindow->Activate(ev);
  1397.                 }
  1398.             }
  1399.         }
  1400.  
  1401.     SOM_CATCH_ALL
  1402.     SOM_ENDTRY
  1403. }
  1404.  
  1405. SOM_Scope ODPlatformWindow  SOMLINK ODWindowStateGetLastFloatingPlatformWindow(ODWindowState *somSelf, Environment *ev)
  1406. {
  1407.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1408.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateGetLastFloatingPlatformWindow");
  1409.  
  1410.     WindowPtr    lastFloatingWindow = kODNULL;
  1411.  
  1412.     SOM_TRY
  1413.     
  1414.         WindowPtr    theWindow;
  1415.         ODWindow*    odWindow;
  1416.         
  1417.         theWindow = ::GetWindowList();
  1418.         lastFloatingWindow = kODNULL;
  1419.         
  1420.         // We have to search the entire window list because we don’t know what the windowKind
  1421.         // of other windows in the list might be, and we have account for the fact that a modal
  1422.         // dialog is up.
  1423.         
  1424.         while (theWindow != kODNULL) 
  1425.         {
  1426.             if (somSelf->IsODWindow(ev,theWindow) != kODFalse) 
  1427.             {
  1428.                 odWindow = somSelf->AcquireODWindow(ev,theWindow);
  1429.                 if (odWindow->IsFloating(ev) != kODFalse)
  1430.                     lastFloatingWindow = theWindow;
  1431.                 ODReleaseObject(ev, odWindow);
  1432.             }
  1433.             theWindow = GetNextWindow(theWindow);
  1434.         }
  1435.         
  1436.     SOM_CATCH_ALL
  1437.     
  1438.         lastFloatingWindow = kODNULL;
  1439.         
  1440.     SOM_ENDTRY
  1441.  
  1442.     return lastFloatingWindow;
  1443. }
  1444.  
  1445. SOM_Scope ODPlatformWindow  SOMLINK ODWindowStateGetFrontNonFloatingPlatformWindow(ODWindowState *somSelf, Environment *ev)
  1446. {
  1447.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1448.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateGetFrontNonFloatingPlatformWindow");
  1449.  
  1450.     
  1451.     WindowPtr    theWindow = kODNULL;
  1452.     ODVolatile(theWindow);
  1453.     
  1454.     SOM_TRY
  1455.     
  1456.         TempODWindow    odWindow = kODNULL;
  1457.         
  1458.         // Get the first visible window in the window list.
  1459.         
  1460.         theWindow = FrontWindow();
  1461.         
  1462.         // Keep searching until a visible window whose windowKind is not
  1463.         // kApplicationFloaterKind is found, or the end of the window list is reached.
  1464.         
  1465.         while ((theWindow != kODNULL) && 
  1466.                 (((odWindow = somSelf->AcquireODWindow(ev,theWindow)) != kODNULL) &&  /* -- TÇ:released down below */
  1467.                      (odWindow->IsFloating(ev) != kODFalse))) 
  1468.         {
  1469.             ODReleaseObject(ev, odWindow); // -- TÇ: to balance the above acquire
  1470.             do 
  1471.             {
  1472.                 theWindow = GetNextWindow(theWindow);
  1473.             } 
  1474.             while ((theWindow != kODNULL) && (GetWindowVisible(theWindow) == kODFalse));
  1475.         }
  1476.     
  1477.  
  1478.     SOM_CATCH_ALL
  1479.     
  1480.         theWindow = kODNULL;
  1481.             
  1482.     SOM_ENDTRY
  1483.  
  1484.     // odWindow is released here on destruction of the TempODWindow, if not in the loop above
  1485.     return theWindow;
  1486.  
  1487. }
  1488.  
  1489. SOM_Scope void  SOMLINK ODWindowStatesomUninit(ODWindowState *somSelf)
  1490. {
  1491.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1492.     ODWindowStateMethodDebug("ODWindowState","ODWindowStatesomUninit");
  1493.  
  1494.     Environment* ev = somGetGlobalEnvironment();
  1495.  
  1496.     ODDeleteObject(_fWindowList);
  1497.     ODSafeReleaseObject(_fBaseMenuBar);        _fBaseMenuBar = kODNULL;
  1498.     ODSafeReleaseObject(_fCurrentMenuBar);    _fCurrentMenuBar = kODNULL;
  1499. }
  1500.  
  1501. SOM_Scope ODSize  SOMLINK ODWindowStatePurge(ODWindowState *somSelf, Environment *ev,
  1502.         ODSize size)
  1503. {
  1504.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1505.     ODWindowStateMethodDebug("ODWindowState","ODWindowStatePurge");
  1506.  
  1507.     return 0;
  1508. }
  1509.  
  1510. SOM_Scope ODWindow*  SOMLINK ODWindowStateRegisterWindow(ODWindowState *somSelf, Environment *ev,
  1511.         ODPlatformWindow newWindow,
  1512.         ODType frameType,
  1513.         ODBoolean isRootWindow,
  1514.         ODBoolean isResizable,
  1515.         ODBoolean isFloating,
  1516.         ODBoolean shouldSave,
  1517.         ODBoolean shouldDispose,
  1518.         ODPart* rootPart,
  1519.         ODTypeToken viewType,
  1520.         ODTypeToken presentation,
  1521.         ODFrame* sourceFrame)
  1522. {
  1523.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1524.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateCreateWindow");
  1525.  
  1526.     ODWindow* window = kODNULL; ODVolatile(window);
  1527.  
  1528.     SOM_TRY
  1529.         
  1530.         window = new ODWindow();
  1531.         if (window == kODNULL)
  1532.             THROW(kODErrCannotCreateWindow); // Note: Should we just use kODErrOutOfMemory?
  1533.             
  1534.         window->InitWindow(ev, newWindow, frameType,
  1535.                             isRootWindow, isResizable, isFloating, shouldSave, shouldDispose,
  1536.                             rootPart, viewType, presentation, sourceFrame);
  1537.         somSelf->AddWindow(ev,window);
  1538.         
  1539.     SOM_CATCH_ALL
  1540.     
  1541.         if (window)
  1542.         {
  1543.             TRY
  1544.                 window->CloseAndRemove(ev);
  1545.             CATCH_ALL
  1546.             ENDTRY
  1547.             window = kODNULL;
  1548.         }
  1549.                     
  1550.     SOM_ENDTRY
  1551.  
  1552.     return window;
  1553. }
  1554.  
  1555. SOM_Scope ODWindow*  SOMLINK ODWindowStateRegisterWindowForFrame(ODWindowState *somSelf, Environment *ev,
  1556.         ODPlatformWindow newWindow,
  1557.         ODFrame* frame,
  1558.         ODBoolean isRootWindow,
  1559.         ODBoolean isResizable,
  1560.         ODBoolean isFloating,
  1561.         ODBoolean shouldSave,
  1562.         ODBoolean shouldDispose,
  1563.         ODFrame* sourceFrame)
  1564. {
  1565.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1566.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateCreateWindow");
  1567.  
  1568.     ODWindow* window = kODNULL; ODVolatile(window);
  1569.  
  1570.     SOM_TRY
  1571.     
  1572.         window = new ODWindow();
  1573.         if (window == kODNULL)
  1574.             THROW(kODErrCannotCreateWindow); // Note: Should we just use kODErrOutOfMemory?
  1575.             
  1576.         window->InitWindowForFrame(ev, newWindow, frame,
  1577.                             isRootWindow, isResizable, isFloating, shouldSave,  shouldDispose, sourceFrame);
  1578.         somSelf->AddWindow(ev,window);
  1579.  
  1580.     SOM_CATCH_ALL
  1581.         
  1582.         if (window)
  1583.         {
  1584.             TRY
  1585.                 window->Close(ev);
  1586.             CATCH_ALL
  1587.             ENDTRY
  1588.             window = kODNULL;
  1589.         }
  1590.             
  1591.     SOM_ENDTRY
  1592.  
  1593.     return window;
  1594. }
  1595.  
  1596. SOM_Scope ODWindow*  SOMLINK ODWindowStateAcquireWindow(ODWindowState *somSelf, Environment *ev,
  1597.         ODID id)
  1598. {
  1599.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1600.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateAcquireWindow");
  1601.  
  1602.     ODWindow* window = kODNULL;
  1603.     
  1604.     SOM_TRY
  1605.     
  1606. /*        LinkedListIterator iter(_fWindowList);
  1607.         
  1608.         for ( WindowLink* link = (WindowLink*) iter.First();
  1609.                 iter.IsNotComplete(); 
  1610.                 link = (WindowLink*) iter.Next())
  1611.         {
  1612.             if (!link->ShouldRemove() && (link->fID == id))
  1613.             {
  1614.                 window = link->fWindow;
  1615.                 break;
  1616.             }
  1617.         }
  1618. */
  1619.             ODWindowIterator* iter = kODNULL; 
  1620.  
  1621.             iter = somSelf->CreateWindowIterator(ev);
  1622.         
  1623.             for (ODWindow* win = iter->First(ev); iter->IsNotComplete(ev);
  1624.                     win = iter->Next(ev))
  1625.             {
  1626.                 if (win->GetID(ev) == id)
  1627.                 {
  1628.                     window = win; 
  1629.                     break;
  1630.                 }
  1631.             }
  1632.             ODDeleteObject(iter);
  1633.  
  1634.             if (window)
  1635.                 window->Acquire(ev);
  1636.  
  1637.     SOM_CATCH_ALL
  1638.         
  1639.         window = kODNULL;
  1640.             
  1641.     SOM_ENDTRY
  1642.  
  1643.     return window;
  1644. }
  1645.  
  1646. SOM_Scope void  SOMLINK ODWindowStateInternalize(ODWindowState *somSelf, Environment *ev,
  1647.         ODDraft* draft)
  1648. {
  1649.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1650.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateInternalize");
  1651.     
  1652.     OrderedCollection* wsuIDCollection = kODNULL; ODVolatile(wsuIDCollection);
  1653.     
  1654.     SOM_TRY
  1655.     
  1656.         // To avoid calling Select in OpenWindows, we use this piece of cross-method state
  1657.         // A better solution might be to change ODOpenDraft to distinguish between the
  1658.         // opendraft and activateopendraft (from the dialog) cases. See also #1295739
  1659.         
  1660.         _fActivateOnOpen = (somSelf->GetRootWindowCount(ev, draft) > 0);
  1661.  
  1662.         ODULong offset, offsetLimit;
  1663.         ODStorageUnitRef suRef;
  1664.         
  1665.         TempODStorageUnit draftProps = draft->AcquireDraftProperties(ev); // -- TÇ tempobj'd
  1666.         
  1667.         if (ODSUExistsThenFocus(ev, draftProps,kODPropRootFrameList, kODStrongStorageUnitRefs))
  1668.         {
  1669.             offsetLimit = draftProps->GetSize(ev);
  1670.     
  1671.             // Get collection of windowstorageunit ids belonging to the draft here.  We'll
  1672.             // use it below to ensure that we don't reopen open windows.
  1673.         
  1674.             wsuIDCollection = new OrderedCollection;
  1675.             WindowPtr theWindow = ::GetWindowList();    
  1676.             while (theWindow != kODNULL)
  1677.             {
  1678.                 if (somSelf->IsODWindow(ev,theWindow) != kODFalse)
  1679.                 {
  1680.                     TempODWindow odWindow = somSelf->AcquireODWindow(ev,theWindow);
  1681.                     if ( ODObjectsAreEqual(ev, odWindow->GetDraft(ev) , draft) )
  1682.                     {
  1683.                         ODStorageUnit* storageU = odWindow->GetRootFrame(ev)->GetStorageUnit(ev);
  1684.                         if ( storageU )
  1685.                             wsuIDCollection->AddLast( (ElementType)(storageU->GetID(ev)) );
  1686.                     }
  1687.                 }
  1688.                 theWindow = GetNextWindow(theWindow);
  1689.             }
  1690.         
  1691.             TempODStorageUnitView draftPropsView = draftProps->CreateView(ev);
  1692.             for (offset = 0; offset < offsetLimit; offset += sizeof(ODStorageUnitRef))
  1693.             {
  1694.                 draftPropsView->SetOffset(ev,offset);
  1695.                 StorageUnitViewGetValue(draftPropsView,ev,sizeof(ODStorageUnitRef), (ODValue)&suRef);
  1696.                 if (draftPropsView->IsValidStorageUnitRef(ev, suRef))
  1697.                 {
  1698.                     ODStorageUnitID wsuID = draftPropsView->GetIDFromStorageUnitRef(ev,suRef);
  1699.                     if ( !wsuIDCollection->Contains((ElementType)wsuID) )
  1700.                     {
  1701.                         ODFrame *rootFrame = draft->AcquireFrame(ev, wsuID);
  1702.                         if (rootFrame)
  1703.                         {
  1704.                             TRY{
  1705.                                 TempODPart rootPart = rootFrame->AcquirePart(ev);
  1706.                                 rootPart->Open(ev, rootFrame);
  1707.                             }CATCH_ALL{
  1708.                                     TRY
  1709.                                         rootFrame->Close(ev);
  1710.                                     CATCH_ALL
  1711.                                     ENDTRY
  1712.                                 RERAISE;
  1713.                             }ENDTRY
  1714.                             rootFrame->Release(ev);
  1715.                         }
  1716.                     }
  1717.                 }
  1718.             }    
  1719.             ODDeleteObject(wsuIDCollection);
  1720.             
  1721.             somSelf->SetDefaultWindowTitles(ev,draft);
  1722.         }
  1723.         
  1724.     SOM_CATCH_ALL
  1725.     
  1726.         ODDeleteObject(wsuIDCollection);
  1727.         
  1728.     SOM_ENDTRY
  1729. }
  1730.  
  1731. SOM_Scope void  SOMLINK ODWindowStateExternalize(ODWindowState *somSelf, Environment *ev,
  1732.         ODDraft* draft)
  1733. {
  1734.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1735.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateExternalize");
  1736.  
  1737.     SOM_TRY
  1738.     
  1739.         somSelf->SetDefaultWindowTitles(ev,draft);
  1740.     
  1741.         ODULong offset, offsetLimit;
  1742.         ODFrame* rootFrame = kODNULL;
  1743.         
  1744.         TempODStorageUnit draftProps = draft->AcquireDraftProperties(ev);
  1745.         
  1746.         ODSUForceFocus(ev, draftProps, kODPropRootFrameList, kODStrongStorageUnitRefs);
  1747.         
  1748.         offset = 0;
  1749.         offsetLimit = draftProps->GetSize(ev);
  1750.     
  1751.         // Use the Window Manager list, since it's ordered
  1752.         // Note: we write the windows out back to front, since we create them in internalize
  1753.         // with the "behind" pointer -1. This only works because ShowODWindow does not bring
  1754.         // the newly shown window in front of the other invisible ones, as does ShowWindow.
  1755.  
  1756.         WindowListIterator iter;
  1757.         
  1758.         for (WindowPtr window = iter.Last(); iter.IsNotComplete(); window = iter.Previous())
  1759.         {
  1760.             if (somSelf->IsODWindow(ev,window))
  1761.             {
  1762.                 TempODWindow odWindow = somSelf->AcquireODWindow(ev,window); // DMc refcount - make temp
  1763.                 if (odWindow 
  1764.                     && (odWindow->ShouldSave(ev)) 
  1765.                     && (ODObjectsAreEqual(ev, odWindow->GetDraft(ev), draft)))
  1766.                 {
  1767.                     if (odWindow->GetStorageUnit(ev) == kODNULL) 
  1768.                     {
  1769.                         TempODStorageUnit    su = draft->CreateStorageUnit(ev);
  1770.                         odWindow->SetStorageUnit(ev, su);
  1771.                     }
  1772.                     odWindow->Externalize(ev);
  1773.     
  1774.                     rootFrame = odWindow->GetRootFrame(ev);
  1775.                     draftProps->SetOffset(ev,offset);    // $opt: Won't the offset be correct automatically? -TC
  1776.                     ODSetStrongSURefProp(ev, draftProps, kODNULL, kODNULL, rootFrame->GetStorageUnit(ev)->GetID(ev));
  1777.                     offset += sizeof(ODStorageUnitRef); // $opt: Won't the offset be correct automatically? -TC
  1778.                 }
  1779.             }
  1780.         }
  1781.         
  1782.         if (offset < offsetLimit)
  1783.             draftProps->DeleteValue(ev,offsetLimit - offset);
  1784.                     
  1785.     SOM_CATCH_ALL
  1786.     SOM_ENDTRY
  1787. }
  1788.  
  1789. SOM_Scope void  SOMLINK ODWindowStateSetDefaultWindowTitles(ODWindowState *somSelf, Environment *ev,
  1790.         ODDraft* draft)
  1791. {
  1792.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1793.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateSetDefaultWindowTitles");
  1794.  
  1795.     //!!! Needs work. Should add counter
  1796.     // Sets default window titles for all root windows of the given draft,
  1797.     // based on the file name.
  1798.  
  1799.     ODWindowIterator* iter = kODNULL; ODVolatile(iter);
  1800.     PlatformFile* file = kODNULL; ODVolatile(file);
  1801.         
  1802.     SOM_TRY
  1803.         
  1804.         ODContainer* container = draft->GetDocument(ev)->GetContainer(ev);
  1805.         
  1806.         file = GetPlatformFileFromContainer(ev, container);
  1807.  
  1808.         char    windowName[256];
  1809.     
  1810.         iter = somSelf->CreateWindowIterator(ev);
  1811.     
  1812.         for (ODWindow* window = iter->First(ev); iter->IsNotComplete(ev);
  1813.                 window = iter->Next(ev))
  1814.         {
  1815.             if ( (ODObjectsAreEqual(ev, window->GetDraft(ev), draft)) && window->IsRootWindow(ev) )
  1816.             {
  1817.                 file->GetAsciiName(windowName,235);
  1818.                 
  1819.                 ODULong draftNum = 0;
  1820.                 
  1821.                 TRY
  1822.                     draftNum = GetDraftNumFromDraft(ev, draft);
  1823.                 CATCH_ALL
  1824.                 ENDTRY
  1825.                 
  1826.                 if (draftNum != 0)
  1827.                 {
  1828.                     CToPascalString(windowName);
  1829.  
  1830.                     const ODSShort kMaxNumberSuffixLength = 10;                    
  1831.                     char theNum[kMaxNumberSuffixLength];
  1832.                     NumToString(draftNum, (StringPtr)theNum); // Macintosh Specific
  1833.  
  1834.                     ODSLong savedRefNum;
  1835.                     BeginUsingLibraryResources(savedRefNum);
  1836.                     ReplaceIntoString( kODDraftTextResID, (StringPtr)windowName,
  1837.                             (StringPtr)theNum, (StringPtr)windowName );
  1838.                     EndUsingLibraryResources(savedRefNum);
  1839.                     PascalToCString((StringPtr)windowName);
  1840.                 }
  1841.     
  1842.                 window->SetWindowTitle(ev, windowName);
  1843.             }
  1844.         }
  1845.         ODDeleteObject(iter);
  1846.         ODDeleteObject(file);
  1847.  
  1848.     SOM_CATCH_ALL
  1849.  
  1850.         ODDeleteObject(iter);
  1851.         ODDeleteObject(file);
  1852.  
  1853.     SOM_ENDTRY
  1854. }
  1855.  
  1856. SOM_Scope void  SOMLINK ODWindowStateOpenWindows(ODWindowState *somSelf, Environment *ev,
  1857.         ODDraft* draft)
  1858. {
  1859.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1860.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateOpenWindows");
  1861.  
  1862.     ODWindowIterator* iter = kODNULL; ODVolatile(iter);
  1863.  
  1864.     SOM_TRY
  1865.  
  1866.         if (draft)
  1867.         {
  1868.             iter = somSelf->CreateWindowIterator(ev);
  1869.         
  1870.             // Windows were externalize/internalized back to front
  1871.             for (ODWindow* window = iter->First(ev); iter->IsNotComplete(ev);
  1872.                     window = iter->Next(ev))
  1873.             {
  1874.                 if (ODObjectsAreEqual(ev, window->GetDraft(ev) , draft))
  1875.                 {
  1876.                     window->Open(ev); // A no-op if its already open
  1877.                     if (_fActivateOnOpen && window->IsShown(ev)) // The draft is already open
  1878.                         window->Select(ev);
  1879.                 }
  1880.             }
  1881.             ODDeleteObject(iter);
  1882.         }
  1883.         _fActivateOnOpen = kODFalse;
  1884.         
  1885.     SOM_CATCH_ALL
  1886.  
  1887.         _fActivateOnOpen = kODFalse;
  1888.         ODDeleteObject(iter);
  1889.  
  1890.     SOM_ENDTRY
  1891.     
  1892. }
  1893.  
  1894. SOM_Scope void  SOMLINK ODWindowStateCloseWindows(ODWindowState *somSelf, Environment *ev,
  1895.         ODDraft* draft)
  1896. {
  1897.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1898.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateCloseWindows");
  1899.  
  1900.     SOM_TRY
  1901.     
  1902.         // For now, since we can't delete while iterating, we make a copy of the list. Yuck.
  1903.     
  1904. /*        LinkedList windowListCopy;    
  1905.     
  1906.         {
  1907.             LinkedListIterator iter(_fWindowList);
  1908.             
  1909.             for ( WindowLink* link = (WindowLink*) iter.First();
  1910.                     iter.IsNotComplete(); 
  1911.                     link = (WindowLink*) iter.Next())
  1912.             {
  1913.                 WindowLink* linkCopy = new WindowLink(link->fID, link->fWindow);
  1914.                 THROW_IF_NULL(linkCopy);
  1915.                 windowListCopy.AddLast(linkCopy);
  1916.             }
  1917.         }
  1918.     
  1919.         LinkedListIterator citer(&windowListCopy);
  1920.         for ( WindowLink* clink = (WindowLink*) citer.First();
  1921.                 citer.IsNotComplete(); 
  1922.                 clink = (WindowLink*) citer.Next())
  1923.         {
  1924.             // Note: Use ID check in case Part closed a subsidiary window
  1925.             // This works now because this is a copy of the list. 
  1926.             // Should probably do a deferred close scheme instead
  1927.             
  1928.             ODWindow* window = somSelf->AcquireWindow(ev, clink->fID);
  1929.             // ODWindow* window = link->fWindow;
  1930.             if (window && (ODObjectsAreEqual(ev, window->GetDraft(ev), draft )))
  1931.             {
  1932.                 window->Close(ev);
  1933.             }
  1934.             ODReleaseObject(ev, window);
  1935.         }
  1936.         windowListCopy.DeleteAllLinks();
  1937. */        
  1938.         
  1939.         ODWindowIterator* iter = somSelf->CreateWindowIterator(ev);
  1940.         
  1941.         for (ODWindow* window = iter->First(ev); iter->IsNotComplete(ev); window = iter->Next(ev))
  1942.         {
  1943.             if (ODObjectsAreEqual(ev, window->GetDraft(ev), draft ))
  1944.             {
  1945.                 window->Acquire(ev); // Close Releases
  1946.                 window->Close(ev);
  1947.             }
  1948.         }
  1949.         ODDeleteObject(iter);
  1950.  
  1951.     
  1952.     SOM_CATCH_ALL
  1953.     SOM_ENDTRY
  1954. }
  1955.  
  1956. SOM_Scope ODUShort  SOMLINK ODWindowStateGetWindowCount(ODWindowState *somSelf, Environment *ev)
  1957. {
  1958.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1959.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateGetWindowCount");
  1960.  
  1961.     ODUShort count = 0;
  1962.  
  1963.     SOM_TRY
  1964.     
  1965.         if (_fWindowList)
  1966.             count = _fWindowList->Count();
  1967.         
  1968.     SOM_CATCH_ALL
  1969.     SOM_ENDTRY
  1970.     
  1971.     return count;
  1972. }
  1973.  
  1974. SOM_Scope ODUShort  SOMLINK ODWindowStateGetRootWindowCount(ODWindowState *somSelf, Environment *ev,
  1975.         ODDraft* draft)
  1976. {
  1977.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  1978.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateGetRootWindowCount");
  1979.  
  1980.     ODUShort count = 0;
  1981.     ODWindowIterator* iter = kODNULL; ODVolatile(iter);
  1982.     
  1983.     SOM_TRY
  1984.     
  1985.         if (draft)
  1986.         {
  1987.             iter = somSelf->CreateWindowIterator(ev);
  1988.         
  1989.             for (ODWindow* window = iter->First(ev); iter->IsNotComplete(ev);
  1990.                     window = iter->Next(ev))
  1991.             {
  1992.                 if (window->IsRootWindow(ev) && (ODObjectsAreEqual(ev, window->GetDraft(ev), draft)))
  1993.                 {
  1994.                     count++;
  1995.                 }
  1996.             }
  1997.             ODDeleteObject(iter);
  1998.         }
  1999.     
  2000.     SOM_CATCH_ALL
  2001.  
  2002.             ODDeleteObject(iter);
  2003.  
  2004.     SOM_ENDTRY
  2005.     
  2006.     return count;
  2007. }
  2008.  
  2009. SOM_Scope ODUShort  SOMLINK ODWindowStateGetTotalRootWindowCount(ODWindowState *somSelf, Environment *ev)
  2010. {
  2011.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  2012.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateGetTotalRootWindowCount");
  2013.  
  2014.     //!!! Should get count directly from collection
  2015.     
  2016.     ODUShort count = 0;
  2017.     ODWindowIterator* iter = kODNULL; ODVolatile(iter);
  2018.     
  2019.     SOM_TRY
  2020.  
  2021.         iter = somSelf->CreateWindowIterator(ev);
  2022.     
  2023.         for (ODWindow* window = iter->First(ev); iter->IsNotComplete(ev);
  2024.                 window = iter->Next(ev))
  2025.         {
  2026.             if (window->IsRootWindow(ev))
  2027.                 count++;
  2028.         }
  2029.         ODDeleteObject(iter);
  2030.         
  2031.     SOM_CATCH_ALL
  2032.  
  2033.         ODDeleteObject(iter);
  2034.  
  2035.     SOM_ENDTRY
  2036.     
  2037.     return count;
  2038. }
  2039.  
  2040. SOM_Scope ODBoolean  SOMLINK ODWindowStateIsODWindow(ODWindowState *somSelf, Environment *ev,
  2041.         ODPlatformWindow aWindow)
  2042. {
  2043.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  2044.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateIsODWindow");
  2045.  
  2046.     ODWindowIterator* iter = kODNULL; ODVolatile(iter);
  2047.     ODBoolean isODWindow = kODFalse;
  2048.         
  2049.     SOM_TRY
  2050.  
  2051.         iter = somSelf->CreateWindowIterator(ev);
  2052.     
  2053.         for (ODWindow* window = iter->First(ev); iter->IsNotComplete(ev);
  2054.                 window = iter->Next(ev))
  2055.         {
  2056.             if (window && (aWindow == window->GetPlatformWindow(ev)))
  2057.             {
  2058.                 isODWindow = kODTrue;
  2059.                 break;
  2060.             }
  2061.         }
  2062.         ODDeleteObject(iter);
  2063.  
  2064.     
  2065.     SOM_CATCH_ALL
  2066.  
  2067.         ODDeleteObject(iter);
  2068.  
  2069.     SOM_ENDTRY
  2070.     
  2071.     return isODWindow;
  2072. }
  2073.  
  2074. SOM_Scope ODWindow*  SOMLINK ODWindowStateAcquireODWindow(ODWindowState *somSelf, Environment *ev,
  2075.         ODPlatformWindow aWindow)
  2076. {
  2077.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  2078.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateAcquireODWindow");
  2079.  
  2080.     ODWindowIterator* iter = kODNULL; ODVolatile(iter);
  2081.     ODWindow* odWindow = kODNULL;
  2082.         
  2083.     SOM_TRY
  2084.     
  2085.         iter = somSelf->CreateWindowIterator(ev);
  2086.     
  2087.         for (ODWindow* window = iter->First(ev); iter->IsNotComplete(ev);
  2088.                 window = iter->Next(ev))
  2089.         {
  2090.             if (window && (aWindow == window->GetPlatformWindow(ev)))
  2091.             {
  2092.                 odWindow = window;
  2093.                 break;
  2094.             }
  2095.         }
  2096.         ODDeleteObject(iter);
  2097.         
  2098.         if (odWindow)
  2099.             odWindow->Acquire(ev);
  2100.  
  2101.     SOM_CATCH_ALL
  2102.  
  2103.         ODDeleteObject(iter);
  2104.         odWindow = kODNULL;
  2105.  
  2106.     SOM_ENDTRY
  2107.     
  2108.     return odWindow;
  2109. }
  2110.  
  2111. SOM_Scope ODWindowIterator*  SOMLINK ODWindowStateCreateWindowIterator(ODWindowState *somSelf, Environment *ev)
  2112. {
  2113.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  2114.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateCreateWindowIterator");
  2115.  
  2116.     ODWindowIterator* iter = kODNULL; ODVolatile(iter);
  2117.     
  2118.     SOM_TRY
  2119.  
  2120.         iter = new ODWindowIterator;
  2121.         THROW_IF_NULL(iter); // "new" does not throw for SOM objects
  2122.         iter->InitWindowIterator(ev, somSelf);
  2123.         
  2124.     SOM_CATCH_ALL
  2125.     
  2126.         ODDeleteObject(iter);
  2127.         
  2128.     SOM_ENDTRY
  2129.     
  2130.     return iter;
  2131. }
  2132.  
  2133. SOM_Scope ODWindow*  SOMLINK ODWindowStateAcquireActiveWindow(ODWindowState *somSelf, Environment *ev)
  2134. {
  2135.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  2136.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateAcquireActiveWindow");
  2137.  
  2138.     ODWindow* aWindow = kODNULL;
  2139.  
  2140.     SOM_TRY
  2141.  
  2142.         WindowPtr platformWindow = kODNULL;
  2143.         
  2144.         //    • First we need to find out the frontmost window
  2145.         platformWindow = somSelf->GetFrontNonFloatingPlatformWindow(ev);
  2146.         
  2147.         if (platformWindow)
  2148.             aWindow = somSelf->AcquireODWindow(ev,platformWindow);
  2149.         
  2150.     SOM_CATCH_ALL
  2151.     SOM_ENDTRY
  2152.     
  2153.     // Not necessary to increment ref count, because AcquireODWindow has done it
  2154.     //if (aWindow)
  2155.     //    aWindow->Acquire(ev);
  2156.     return aWindow;
  2157. }
  2158.  
  2159. SOM_Scope void  SOMLINK ODWindowStateSetBaseMenuBar(ODWindowState *somSelf, Environment *ev,
  2160.         ODMenuBar* theMenuBar)
  2161. {
  2162.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  2163.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateSetBaseMenuBar");
  2164.  
  2165.     SOM_TRY
  2166.         
  2167.         // $$$$$ Change this error code to be more explicit. -VL
  2168.         ASSERT(theMenuBar, kODErrIllegalNullInput);
  2169.     
  2170.         if (!ODObjectsAreEqual(ev, theMenuBar, _fBaseMenuBar))
  2171.         {
  2172.             ODULong generation;
  2173.             if (_fBaseMenuBar)
  2174.                 generation = _fBaseMenuBar->GetGeneration(ev) + 1;
  2175.             else
  2176.                 generation = 1;
  2177.             ODReleaseObject(ev, _fBaseMenuBar);
  2178.             theMenuBar->Acquire(ev);
  2179.             _fBaseMenuBar = theMenuBar;
  2180.             _fBaseMenuBar->SetGeneration(ev,generation);
  2181.         }
  2182.  
  2183.     SOM_CATCH_ALL
  2184.     SOM_ENDTRY
  2185. }
  2186.  
  2187. SOM_Scope ODMenuBar*  SOMLINK ODWindowStateCopyBaseMenuBar(ODWindowState *somSelf, Environment *ev)
  2188. {
  2189.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  2190.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateCopyBaseMenuBar");
  2191.     
  2192.     ODMenuBar* menuBar = kODNULL;
  2193.     
  2194.     SOM_TRY
  2195.  
  2196.         if (_fBaseMenuBar)
  2197.             menuBar = _fBaseMenuBar->Copy(ev);
  2198.     
  2199.     SOM_CATCH_ALL
  2200.     SOM_ENDTRY
  2201.     
  2202.     return menuBar;    // -- TÇ: CopyBaseMenuBar is an 'acquire' function.
  2203. }
  2204.  
  2205. SOM_Scope void  SOMLINK ODWindowStateAdjustPartMenus(ODWindowState *somSelf, Environment *ev)
  2206. {
  2207.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  2208.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateAdjustPartMenus");
  2209.  
  2210.     SOM_TRY
  2211.  
  2212.         TempODFrame targetFrame 
  2213.             = _fSession->GetArbitrator(ev)->AcquireFocusOwner(ev,_fMenuFocus);
  2214.             
  2215.         // To support root menu items like Print. 
  2216.         // Other platforms may choose to add a new focus for this
  2217.         
  2218.         ODFrame* rootFrame;
  2219.         { TempODWindow window = somSelf->AcquireActiveWindow(ev) ;    
  2220.           rootFrame = window ? window->GetRootFrame(ev) : kODNULL;
  2221.         }
  2222.         
  2223.         if (rootFrame)
  2224.         {
  2225.             TempODPart targetPart = rootFrame->AcquirePart(ev); // -- TÇ tempobj'd
  2226.             targetPart->AdjustMenus(ev,rootFrame);
  2227.         }    
  2228.             
  2229.         if (targetFrame && (targetFrame != rootFrame))
  2230.         {
  2231.             TempODPart targetPart = targetFrame->AcquirePart(ev); // -- TÇ tempobj'd
  2232.             targetPart->AdjustMenus(ev,targetFrame);
  2233.         }
  2234.         
  2235.     SOM_CATCH_ALL
  2236.     SOM_ENDTRY
  2237. }
  2238.  
  2239. SOM_Scope ODMenuBar*  SOMLINK ODWindowStateCreateMenuBar(ODWindowState *somSelf, Environment *ev,
  2240.         ODPlatformMenuBar menuBar)
  2241. {
  2242.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  2243.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateCreateMenuBar");
  2244.  
  2245.     ODMenuBar* mb = kODNULL;  ODVolatile(mb);
  2246.  
  2247.     SOM_TRY
  2248.     
  2249.         mb = new ODMenuBar;
  2250.         THROW_IF_NULL(mb);    // "new" does not THROW for SOM objects
  2251.         mb->InitMenuBar(ev, _fSession, menuBar);
  2252.     
  2253.     SOM_CATCH_ALL
  2254.  
  2255.         ODDeleteObject(mb);
  2256.  
  2257.     SOM_ENDTRY
  2258.         
  2259.     return mb;
  2260. }
  2261.  
  2262. SOM_Scope ODCanvas*  SOMLINK ODWindowStateCreateCanvas(ODWindowState *somSelf, Environment *ev,
  2263.         ODGraphicsSystem graphicsSystem,
  2264.         ODPlatformCanvas platformCanvas,
  2265.         ODBoolean isDynamic,
  2266.         ODBoolean isOffscreen)
  2267. {
  2268.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  2269.     ODWindowStateMethodDebug("ODWindowState","CreateCanvas");
  2270.  
  2271.     ODCanvas* canvas = kODNULL;  ODVolatile(canvas);
  2272.  
  2273.     SOM_TRY
  2274.  
  2275.         canvas = new ODCanvas;
  2276.         THROW_IF_NULL(canvas);    // "new" does not THROW for SOM objects
  2277.         canvas->InitCanvas(ev, graphicsSystem,platformCanvas,isDynamic,isOffscreen);
  2278.         
  2279.     SOM_CATCH_ALL
  2280.     
  2281.         ODDeleteObject(canvas);
  2282.         
  2283.     SOM_ENDTRY
  2284.     
  2285.     return canvas;
  2286. }
  2287.  
  2288. SOM_Scope ODFacet*  SOMLINK ODWindowStateCreateFacet(ODWindowState *somSelf, Environment *ev,
  2289.         ODFrame* frame,
  2290.         ODShape* clipShape,
  2291.         ODTransform* externalTransform,
  2292.         ODCanvas* canvas,
  2293.         ODCanvas* biasCanvas)
  2294. {
  2295.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  2296.     ODWindowStateMethodDebug("ODWindowState","CreateFacet");
  2297.  
  2298.     ODFacet* facet = kODNULL;  ODVolatile(facet);
  2299.     
  2300.     SOM_TRY
  2301.  
  2302.         facet = new ODFacet;
  2303.         THROW_IF_NULL(facet);    // "new" does not THROW for SOM objects
  2304.         facet->InitFacet(ev, frame, clipShape, externalTransform, canvas, biasCanvas);
  2305.     
  2306.     SOM_CATCH_ALL
  2307.     
  2308.         ODDeleteObject(facet);
  2309.         
  2310.     SOM_ENDTRY
  2311.     
  2312.     return facet;
  2313. }
  2314.  
  2315. SOM_Scope void    SOMLINK ODWindowStateRepairWindowOrder(ODWindowState *somSelf, Environment *ev)
  2316. {
  2317.     ODWindowStateData *somThis = ODWindowStateGetData(somSelf);
  2318.     ODWindowStateMethodDebug("ODWindowState","ODWindowStateRepairWindowOrder");
  2319.  
  2320.     // ODWindowState calls this private method when it suspects that some alien code
  2321.     // (the toolbox or an INIT) has messed with the Window Manager window list behind
  2322.     // its back.  This method will force all non-floating ODWindows to be behind all
  2323.     // floating ODWindows.  Non-ODWindows are ignored.  
  2324.     //
  2325.     // BUG: If there are nested dialogs,
  2326.     // AND the inner dialog calls ActivateFrontWindows (which calls this method) upon
  2327.     // dismissal (which it should), AND the outer dialog (which is now the top window) is
  2328.     // an ODWindow, then this method will move the outer dialog to appear behind the floaters.
  2329.     // There is currently no way to tell that a non-floating window is actually a modal
  2330.     // dialog window.  It turns out that this behavior shouldn't be a problem: because the
  2331.     // outer dialog is an ODWindow, it's frame will take the selection focus, causing
  2332.     // all floaters owned by other frames to be hidden.  Thus, when the inner dialog is
  2333.     // dismissed, the outer dialog is forced behind the floaters, but they are hidden,
  2334.     // so the user can't tell that the layering is "wrong."  I actually tested this with
  2335.     // Cyberdog.  Lucky!
  2336.     //
  2337.     // ANOTHER BUG: This method assumes that the caller to ActivateFrontWindows is first
  2338.     // doing the DisposeDialog.  If DisposeDialog is called after ActivateFrontWindows,
  2339.     // we'll still get the same ordering problem.  Fortunately, this can be fixed by the
  2340.     // part developer.
  2341.     // -CSL  7/30/96
  2342.  
  2343.     ODWindowIterator* iter = kODNULL; ODVolatile(iter);
  2344.     WindowPtr bottomFloatingMacWin = kODNULL;
  2345.     
  2346.     SOM_TRY
  2347.         
  2348.         // 1. Find bottom floating ODWindow
  2349.  
  2350.         // Note: It would seem to make sense to traverse the Window Manager (WM) window list
  2351.         // and check each window to see if it's a floating ODWindow.  Doing this is
  2352.         // very expensive because calling AcquireODWindow creates an iterator every time.
  2353.         // Instead, we do it the other way around--iterate through the non-ordered ODWindow
  2354.         // list and for each floater, find it by inexpensively traversing the WM window list.
  2355.         // This routine should be lightweight.
  2356.         iter = somSelf->CreateWindowIterator( ev );
  2357.         for (ODWindow* currentODWin = iter->First( ev ); iter->IsNotComplete( ev );
  2358.                 currentODWin = iter->Next( ev ))
  2359.         {
  2360.             // If it's a floater, find it in the WM List
  2361.             if ( currentODWin->IsFloating( ev ))
  2362.             {
  2363.                 // Traverse WM list
  2364.                 WindowPtr targetMacWin = currentODWin->GetPlatformWindow( ev );
  2365.                 ODBoolean targetIsDeeper = kODFalse;
  2366.                 WindowPtr currentMacWin = GetWindowList();
  2367.                 while ( currentMacWin )
  2368.                 {
  2369.                     if ( currentMacWin == bottomFloatingMacWin )
  2370.                         targetIsDeeper = kODTrue;
  2371.                         
  2372.                     if ( currentMacWin == targetMacWin )    // Found it
  2373.                     {
  2374.                         if ( targetIsDeeper || bottomFloatingMacWin == kODNULL )
  2375.                             bottomFloatingMacWin = targetMacWin;
  2376.                         break;
  2377.                     }
  2378.                     currentMacWin = GetNextWindow( currentMacWin );
  2379.                     WASSERTM( currentMacWin, "Didn't find the ODWindow!" );
  2380.                 }
  2381.             }
  2382.         }
  2383.  
  2384.         // 2. For all non-floating ODWindows on top of the bottom floater call SendBehind,
  2385.         // but don't alter the relative order of the non-floaters.
  2386.         if ( bottomFloatingMacWin != kODNULL )
  2387.         {
  2388.             // In this case we must make the outside loop walk the Window Manager list because
  2389.             // we need to move misplaced windows back in the correct order.  The inside loop
  2390.             // is actually embedded in the call to AcquireODWindow.  In most cases, there will
  2391.             // only be one window that needs to be moved, so the expense here isn't bad.
  2392.             WindowPtr sendBehindMacWin = bottomFloatingMacWin;
  2393.             WindowPtr currentMacWin = GetWindowList();
  2394.             while ( currentMacWin != kODNULL && currentMacWin != bottomFloatingMacWin )
  2395.             {
  2396.                 TempODWindow currentODWin = somSelf->AcquireODWindow( ev, currentMacWin );
  2397.                 if ( currentODWin != kODNULL && !currentODWin->IsFloating( ev ))
  2398.                 {
  2399.                     WindowPtr nextMacWin = GetNextWindow( currentMacWin );
  2400.                     SendBehind( currentMacWin, sendBehindMacWin );
  2401.                     sendBehindMacWin = currentMacWin;
  2402.                     currentMacWin = nextMacWin;
  2403.                 }
  2404.                 else
  2405.                     currentMacWin = GetNextWindow( currentMacWin );
  2406.             }
  2407.         }
  2408.  
  2409.         ODDeleteObject( iter );
  2410.  
  2411.     SOM_CATCH_ALL
  2412.  
  2413.         if ( iter )
  2414.             ODDeleteObject( iter );
  2415.  
  2416.     SOM_ENDTRY
  2417. }
  2418.